package org.alis.smallcc.designpatterns.behavior.observer;

import java.io.Serializable;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * 被观察者 抽象类
 * 
 * @author luochuan
 */
public abstract class Observable {


	private Set<Observer> set = new CopyOnWriteArraySet<>();
	private Boolean isTransmitThis = Boolean.FALSE;

	public final void setTransmitThis(Boolean bool) {
		isTransmitThis = bool;
	}

	/**
	 * 通知指定用户
	 * 
	 * @param function  获取参数的接口
	 * @param predicate 配置凭据
	 */
	public final <P extends Serializable> void notify(Function<? super Observer, P> function, Predicate<? super Observer> predicate) {
		set.stream().filter(predicate).forEach(obs -> {
			if (Boolean.TRUE.equals(isTransmitThis)) {
				obs.update(this, function.apply(obs));
			} else {
				obs.update(function.apply(obs));
			}
		});
	}

	/**
	 * 通知所有的用户
	 * 
	 * @param function  获取参数的接口
	 * @param predicate 配置凭据
	 */
	public final <P  extends Serializable> void notifyAll(Function<? super Observer, P> function) {
		set.stream().forEach(obs -> {
			if (Boolean.TRUE.equals(isTransmitThis)) {
				obs.update(this, function.apply(obs));
			} else {
				obs.update(function.apply(obs));
			}
		});
	}

	public final void register(Observer observer) {
		set.add(observer);
	}
	
	/**
	 * 观察者有多少个
	 * @return 
	 */
	public final int size() {
		return set.size();
	}
	
	/**
	 * 获取被观察者的名称
	 * @return
	 */
	public abstract String getName();
	
	/**
	 * 通知观察者
	 */
	public abstract void notifyObserver();
}
